package com.amigo.online.provider.manager.service.impl;

import java.io.File;
import java.io.FileInputStream;

import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.Resource;

import org.jboss.logging.Logger;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.amigo.online.common.base.service.BaseService;
import com.amigo.online.provider.manager.mapper.MusicTblMapper;
import com.amigo.online.provider.manager.mapper.VideoMapper;
import com.amigo.online.provider.manager.model.entity.MusicTbl;
import com.amigo.online.provider.manager.model.entity.Video;
import com.amigo.online.provider.manager.service.VideoService;
import com.amigo.online.provider.manager.util.FastDFSClient;
import com.amigo.online.provider.manager.util.TimestampUtil;
import com.amigo.online.provider.manager.util.param.dto.PageDto;
import com.amigo.online.provider.manager.util.video.download.VideoDownload;
import com.amigo.online.provider.manager.util.video.processing.FFMPEG;
import com.amigo.online.provider.manager.util.video.processing.FFMpegMusicUtil;
import com.amigo.online.provider.manager.util.video.size.ReadVideo;
import com.amigo.online.provider.manager.util.video.uploading.QiniuUtil;

@Service
public class VideoServiceImpl extends BaseService<Video> implements VideoService {
    private static final Logger logger = Logger.getLogger(VideoServiceImpl.class);
    @Resource
    private VideoMapper videoMapper;
    @Resource
    private MusicTblMapper musicTblMapper;

    @SuppressWarnings("unused")
    @Autowired
    private QiniuUtil qiniuUtil;
    @Autowired
    private FFMpegMusicUtil ffMpegMusicUtil;

    @SuppressWarnings("unused")
    private static String VIDEO_ADDRESS;// 上传的七牛云地址(存入数据库)
    private static String FFMPEG_PATH;// ffmpeg程序位置
    private static String ORIGINAL_VIDEO_ADDRESS;// 下载后存放的视频地址
    private static String MODIFIED_VIDEO;// 裁剪后的视频地址

    @Value("${video_address}")
    public void setVIDEO_ADDRESS(String vIDEO_ADDRESS) {
        VIDEO_ADDRESS = vIDEO_ADDRESS;
    }

    @Value("${ffmpeg_path}")
    public void fFMPEG_PATH(String fFMPEG_PATH) {
        FFMPEG_PATH = fFMPEG_PATH;
    }

    @Value("${original_video_address}")
    public void oRIGINAL_VIDEO_ADDRESS(String oRIGINAL_VIDEO_ADDRESS) {
        ORIGINAL_VIDEO_ADDRESS = oRIGINAL_VIDEO_ADDRESS;
    }

    @Value("${modified_video}")
    public void mODIFIED_VIDEO(String mODIFIED_VIDEO) {
        MODIFIED_VIDEO = mODIFIED_VIDEO;
    }

    @Override
    public List<Video> findVideoList(Video video) {
        return videoMapper.findVideoList(video);

    }

    @Override
    public boolean saveVideo(Video video) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    // url
                    String content = video.getDownloadurl();
                    // 获取视频标题
                    String videoName = video.getTitle();
                    // 存入本地的视频地址
                    String localityUrl = ORIGINAL_VIDEO_ADDRESS + videoName + ".mp4";
                    // 下载到本地
                    boolean bb = VideoDownload.httpDownload(content, localityUrl);
                    if (bb) {
                        // 获取下载视频的长和宽
                        PageDto size = ReadVideo.videosize(localityUrl);
                        // 视频尺寸
                        double videoSize = (double) Math.round(video.getVideoSize() * 100) / 100;
                        // 裁剪后的高度
                        int height = (int) (size.getVideoHeight() * videoSize);
                        // 宽度不变
                        int width = size.getVideoWidth();

                        // 截取后的视频名称
                        String randomNumberName = video.getTitle() + TimestampUtil.timestampRandomNumbers();
                        String randomNumber = randomNumberName + ".mp4";

                        // 截取后的视频位置
                        String vdn = MODIFIED_VIDEO + randomNumber;
                        logger.info("url截取后的视频位置:" + vdn);
                        HashMap<String, String> dto = new HashMap<String, String>();
                        // ffmpeg程序地址
                        dto.put("ffmpeg_path", FFMPEG_PATH);// 必填
                        // 原视频
                        dto.put("input_path", localityUrl);// 必填
                        dto.put("width", String.valueOf(width));// 必填
                        dto.put("height", String.valueOf(height));// 必填
                        // 裁剪后视频
                        dto.put("video_converted_path", vdn);
                        new FFMPEG().videoTransfer(dto);
                        // 获取视频第一帧并上传服务器
                        String cover = ffMpegMusicUtil.getVideoPhoto(vdn, randomNumberName, width, height, 00, 00, 00);
                        logger.info("url图片上传地址:" + cover);
                        // 上传七牛云
                        // Response res = qiniuUtil.upload(vdn, randomNumber);

                        File ff = new File(vdn);
                        FileInputStream fs = new FileInputStream(ff);
                        byte[] bytes = new byte[fs.available()];
                        // 将文件内容写入字节数组，提供测试的case
                        fs.read(bytes);
                        String ava = null;
                        try {
                            // 获取视频长传地址
                            ava = FastDFSClient.uploadFile(bytes, null);
                            fs.close();
                            logger.info("视频上传地址:" + ava);

                        } catch (Exception e) {
                            logger.error("上传失败,视频地址:" + ava);
                        }

                        // 上传获取视频的音频后获取 上传
                        String musicUrl = ffMpegMusicUtil.videoToMusic(vdn, TimestampUtil.timestampRandomNumbers());
                        logger.info("音频上传地址:" + musicUrl);
                        // 上传成功后删除本地視频文件
                        File file = new File(localityUrl);
                        logger.info("原视频地址------:" + localityUrl);
                        File file2 = new File(vdn);
                        logger.info("裁剪后的视频地址-------:" + vdn);
                        file.delete();
                        file2.delete();
                        video.setWidth(width);
                        video.setHeight(height);
                        // String videourl = VIDEO_ADDRESS + randomNumber;
                        video.setVideo(ava);
                        video.setUpdatedTime(video.getCreatedTime());
                        video.setCover(cover);
                        // 添加到视频表
                        int vsv = videoMapper.saveVideo(video);
                        if (vsv <= 0) {
                            logger.error("视频文件添加失败,视频路径：" + randomNumber);
                        } else {
                            MusicTbl mt = new MusicTbl();
                            Video video = videoMapper.getVideo(ava);
                            int videoid = new Long(video.getId()).intValue();
                            mt.setUserId(0);
                            mt.setName(TimestampUtil.timestampRandomNumbers());
                            mt.setVideoId(videoid);
                            mt.setMusic(musicUrl);
                            mt.setCreatedTime(System.currentTimeMillis());
                            musicTblMapper.saveMusicTbl(mt);
                        }

                    } else {
                        logger.error("视频文件下载失败,视频下载地址" + video.getDownloadurl());
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        executorService.shutdown();
        return true;
    }

    @Override
    public boolean deleteVideo(Video video) {
        video.setDeletedTime(System.currentTimeMillis());
        if (videoMapper.deleteVideo(video) <= 0) {
            return false;
        } else {
            return true;
        }
    }

    @Override
    public boolean saveLocalVideo(Video video) {
        logger.info("=====================================================================");
        logger.info("执行本地上传视频!");
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.execute(new Runnable() {
            @Override
            public void run() {
                try {
                    // 获取下载视频的长和宽
                    PageDto size = ReadVideo.videosize(video.getLocalAddress());
                    // 视频尺寸
                    double videoSize = (double) Math.round(video.getVideoSize() * 100) / 100;
                    // 裁剪后的高度
                    int height = (int) (size.getVideoHeight() * videoSize);
                    // 宽度不变
                    int width = size.getVideoWidth();

                    // 截取后的视频名称
                    String randomNumberName = video.getTitle() + TimestampUtil.timestampRandomNumbers();
                    String randomNumber = randomNumberName + video.getSuffix();
                    // 截取后的视频位置
                    String vdn = MODIFIED_VIDEO + randomNumber;
                    HashMap<String, String> dto = new HashMap<String, String>();
                    // ffmpeg程序地址
                    dto.put("ffmpeg_path", FFMPEG_PATH);// 必填
                    // 原视频
                    dto.put("input_path", video.getLocalAddress());// 必填
                    dto.put("width", String.valueOf(width));// 必填
                    dto.put("height", String.valueOf(height));// 必填
                    // 裁剪后视频
                    dto.put("video_converted_path", vdn);
                    new FFMPEG().videoTransfer(dto);
                    // 上传视频第一祯
                    // String cover = ffMpegMusicUtil.getThumb(vdn, randomNumberName, width,
                    // height,00, 00, 01);
                    logger.info("执行上传视频第一帧");
                    String cover = ffMpegMusicUtil.getVideoPhoto(vdn, randomNumberName, width, height, 00, 00, 00);
                    logger.info("执行上传视频第一帧完成,线上地址:" + cover);
                    // 上传获取视频的音频后获取 上传
                    // String musicUrl = ffMpegMusicUtil.videoToAudio(vdn,
                    // TimestampUtil.timestampRandomNumbers());
                    logger.info("执行上传音频");
                    String musicUrl = ffMpegMusicUtil.videoToMusic(vdn, TimestampUtil.timestampRandomNumbers());
                    logger.info("执行上传音频完成,音频地址:" + musicUrl);
                    File ff = new File(vdn);
                    FileInputStream fs = new FileInputStream(ff);
                    byte[] bytes = new byte[fs.available()];
                    // 将文件内容写入字节数组，提供测试的case
                    fs.read(bytes);
                    String ava = null;

                    try {
                        // 获取视频长传地址
                        logger.info("开始上传视频");
                        ava = FastDFSClient.uploadFile(bytes, null);
                        fs.close();
                        logger.info("上传成功,视频上传地址:" + ava);

                    } catch (Exception e) {
                        logger.error("上传失败,视频地址:" + ava);
                    }
                    logger.info("开始执行删除原视频和裁剪后的视频！");
                    // 上传成功后删除本地視频文件
                    File file = new File(video.getLocalAddress());
                    logger.info("原视频地址------:" + video.getLocalAddress());
                    File file2 = new File(vdn);
                    logger.info("裁剪后的视频地址-------:" + vdn);
                    file.delete();
                    file2.delete();
                    video.setWidth(width);
                    video.setHeight(height);
                    video.setVideo(ava);
                    video.setUpdatedTime(video.getCreatedTime());
                    video.setCover(cover);
                    // 添加到视频表
                    int vsv = videoMapper.saveVideo(video);
                    if (vsv <= 0) {
                        logger.info("视频文件添加失败,视频路径：" + randomNumber);
                    } else {
                        MusicTbl mt = new MusicTbl();
                        Video vd = videoMapper.getVideo(ava);
                        int videoid = new Long(vd.getId()).intValue();
                        mt.setUserId(0);
                        mt.setName(TimestampUtil.timestampRandomNumbers());
                        mt.setVideoId(videoid);
                        mt.setMusic(musicUrl);
                        mt.setCreatedTime(System.currentTimeMillis());
                        musicTblMapper.saveMusicTbl(mt);
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        executorService.shutdown();
        return true;

    }

    @Override
    public List<Video> findUserVideoList(Video video) {

        return videoMapper.findUserVideoList(video);
    }

    @Override
    public boolean updateVideo(Video video) {

        video.setUpdatedTime(System.currentTimeMillis() / 1000);
        if (videoMapper.updateVideo(video) <= 0) {
            return false;
        } else {
            return true;
        }

    }

    @Override
    public boolean saveHotVideo(Video video) {
        video.setRecommended(1);
        video.setHot(1);
        video.setWeight(videoMapper.getVideoMaximalWeight() + 0.05);
        video.setUpdatedTime(System.currentTimeMillis() / 1000);
        return videoMapper.updateVideo(video) > 0;
    }

    @Override
    public List<Video> findRecommendVideoList(Video video) {
        video.setRecommended(1);
        return videoMapper.findRecommendVideoList(video);
    }

    @Override
    public boolean deleteRecommendVideo(Video video) {
        video.setRecommended(0);
        video.setUpdatedTime(System.currentTimeMillis() / 1000);
        return videoMapper.updateVideo(video) > 0;
    }

}
